Ранее мы использовали загрузку с TF-карты, что соответствует аппаратному интерфейсу SD0. Теперь, чтобы изменить способ загрузки и загружать систему с eMMC, необходимо внести некоторые изменения в предыдущую конфигурацию:
В блоковом дизайне Vivado необходимо включить SD1 (eMMC подключен к интерфейсу SD1 на основной плате):
Продолжите последующие операции: "Generate Bitstream" --> "Export Hardware" --> Экспорт файла .xsa.
Скопируйте файл .xsa из Windows на виртуальную машину через общую папку, затем скопируйте файл xsa из общей папки в рабочий каталог:
Запустите среду Petalinux в рабочем каталоге и выполните соответствующую настройку: используйте команду:
xspetapetalinux-config --get-hw-description=.#Импорт нового xsa и завершение конфигурации
Настройте uboot на qspi-flash, а image и rootfs — на eMMC:
Разметка qspi-flash:
xxxxxxxxxxpetalinux-config --get-hw-description=.Subsystem AUTO Hardware Settings-->Flash Settings-->Файловая система находится на mmcblk1p2.
xxxxxxxxxxpetalinux-config --get-hw-description=.Image Packaging Configuration--->
Выберите ps7_sd_1. ps7_sd_1 соответствует eMMC.
xxxxxxxxxxpetalinux-config --get-hw-description=.Subsystem AUTO Hardware Settings-->SD/SDIO Settings-->
xxxxxxxxxxpetalinux-config --get-hw-description=.petalinux-config -> u-boot configuration ->u-boot script configuration -> QSPI/SPI image offsets# Здесь Zynq использует image.ub (который содержит ядро и dtb, image.ub является fit image)xxxxxxxxxxpetalinux-config -c u-boot ARM architecture -> (0xFE0000) Boot script offset# 0xFE0000 соответствует начальному адресу bootsrc в qspi flashКомпиляция и упаковка
xxxxxxxxxxpetalinux-buildpetalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --u-boot --fpga --force#На этом этапе генерируются boot.src/BOOT.bin/image.ub/roofs.tar.gzСначала настройте отладочную плату на режим загрузки с SD-карты, подключите сетевой кабель, включите питание и создайте папку image в её каталоге /home/root. Затем по FTP скопируйте сгенерированные на виртуальной машине image.ub и roofs.tar.gz в каталог image. На этом этапе образ ядра и файловая система для режима eMMC временно хранятся на TF-карте.
Скопируйте сгенерированные файлы BOOT.bin/image.ub/zynq_fsbl.elf/boot.src в среду Windows. Установите отладочную плату в режим JTAG, включите питание и используйте утилиту Vitis для прошивки flash (program flash tool), чтобы записать файлы BOOT.bin/image.ub/zynq_fsbl.elf/boot.src в qspi-flash (конкретные адреса для записи см. в предыдущей информации о разделах qspi-flash):
(1) Запись BOOT.bin: выберите BOOT.bin в качестве файла образа, укажите смещение 0x0000000.
(2) Запись image.ub: сначала переименуйте image.ub в image.ub.bin; затем выберите image.ub.bin в качестве файла образа, укажите смещение 0x5A0000.
(3) Запись boot.src: сначала переименуйте boot.src в boot.src.bin; затем выберите boot.src.bin в качестве файла образа, укажите смещение 0xFE0000:
После запуска uboot загрузит скрипт boot.src. В этом скрипте будут выполнены соответствующие операции чтения, загрузки и bootm в зависимости от текущего режима загрузки.
Форматирование и разметка eMMC
Выключите питание, установите режим загрузки с SD-карты, вставьте TF-карту в слот, включите питание, чтобы войти в систему Linux на TF-карте.
Удаление существующих разделов eMMC и создание новых
xxxxxxxxxx# Проверьте, есть ли у текущих разделов eMMC точки монтированияmount# Если смонтированы, сначала отмонтируйтеumount /dev/mmcblk1p1umount /dev/mmcblk1p2# Форматирование eMMC#fdisk /dev/mmcblk1Удаление разделов
Введите "p", чтобы увидеть текущую ситуацию с разделами.
Введите "d", чтобы удалить раздел. Если разделов несколько, введите "d" несколько раз.
Снова введите "p", чтобы увидеть текущую ситуацию с разделами.
Создание первого раздела
Введите "n", чтобы создать раздел. Введите "p" (основной раздел), затем "1" (номер раздела), "2048" (первый сектор), "+1G" (выделить 1 ГБ для первого раздела) или напрямую укажите последний сектор.
Введите "t", чтобы установить тип раздела, введите "b", чтобы установить тип "W95 FAT32".
Повторный ввод "p" отобразит текущий статус раздела, включая номер конечного сектора текущего раздела (соответствующий EndLBA).
Создание второго раздела
Используйте команду "n", введите "p" (основной раздел), затем "2", и оставьте оставшееся пространство для второго раздела, просто нажав enter.
Если при создании второго раздела первый сектор не увеличивается на основе номера конечного сектора первого раздела, введите значение EndLBA предыдущего раздела + 1.
Проверка таблицы разделов
Введите "p", чтобы проверить, есть ли два раздела; если все правильно, введите "w", чтобы записать таблицу разделов на TF-карту.
Форматирование разделов
xxxxxxxxxx# Форматирование первого раздела в FAT32mkfs.vfat -F 32 /dev/mmcblk1p1# Форматирование второго раздела в EXT4mkfs.ext4 /dev/mmcblk1p2 Скопируйте и извлеките файлы image.ub и roofs.tar.gz для загрузки eMMC с карты TF в разделы eMMC.
xxxxxxxxxx# Create two folders as mount points for the two eMMC partitionsmkdir /media/mmcblk1p1mkdir /media/mmcblk1p2# Mount /dev/mmcblk1p1 to /media/mmcblk1p1mount /dev/mmcblk1p1 /media/mmcblk1p1# Mount /dev/mmcblk1p2 to /mnt/mmcblk1p2mount /dev/mmcblk1p2 /media/mmcblk1p2# Copy image.ub to /dev/mmcblk1p1cp /home/root/image/image.ub /media/mmcblk1p1sync
# Extract rootfs.tar.gz to /dev/mmcblk1p2tar -xzf /home/root/image/rootfs.tar.gz -C /media/mmcblk1p2syncПримечание: поскольку образ загружается из qspi-flash, также приемлемо не копировать image.ub на первый раздел.
Выключите устройство, установите режим загрузки spi-flash и включите его. В этот момент uboot и ядро будут загружены из qspi-flash, а файловая система — из eMMC.
После запуска U-Boot загружает скрипт boot.src. Этот скрипт выполняет соответствующие операции чтения, загрузки и загрузки в зависимости от текущего режима загрузки.
Ниже приведено содержимое файла boot.src по умолчанию:
xxxxxxxxxx# Traverse boot mode (JTAG/QSPI/MMC/NAND)for boot_target in ${boot_targets};do echo "Trying to load boot images from ${boot_target}" if test "${boot_target}" = "jtag" ; then bootm 0x00200000 0x04000000 0x00100000 fi if test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1" ; then # If booting from mmc, check whether there is a uEnv.txt file # under mmc (current petalinux does not contain this file) if test -e ${devtype} ${devnum}:${distro_bootpart} /uEnv.txt; then # load uEnv.txt fatload ${devtype} ${devnum}:${distro_bootpart} 0x02080000 uEnv.txt; echo "Importing environment(uEnv.txt) from ${boot_target}..." env import -t 0x02080000 $filesize if test -n $uenvcmd; then echo "Running uenvcmd ..."; run uenvcmd; fi fi # If the mmc contains the image.ub file if test -e ${devtype} ${devnum}:${distro_bootpart} /image.ub; then # load image.ub to 0x10000000 fatload ${devtype} ${devnum}:${distro_bootpart} 0x10000000 image.ub; # boot from 0x10000000 bootm 0x10000000; fi # If you start from mmc, the following code will not be executed normally. # If mmc contains uImage file and system.dtb file if test -e ${devtype} ${devnum}:${distro_bootpart} /uImage; then fatload ${devtype} ${devnum}:${distro_bootpart} 0x00200000 uImage;; fi if test -e ${devtype} ${devnum}:${distro_bootpart} /system.dtb; then fatload ${devtype} ${devnum}:${distro_bootpart} 0x00100000 system.dtb; fi # If mmc contains ramdisk.cpio.gz.u-boot file if test -e ${devtype} ${devnum}:${distro_bootpart} /ramdisk.cpio.gz.u-boot && test "${skip_tinyramdisk}" != "yes"; then fatload ${devtype} ${devnum}:${distro_bootpart} 0x04000000 ramdisk.cpio.gz.u-boot; bootm 0x00200000 0x04000000 0x00100000 fi if test -e ${devtype} ${devnum}:${distro_bootpart} /rootfs.cpio.gz.u-boot && test "${skip_ramdisk}" != "yes"; then fatload ${devtype} ${devnum}:${distro_bootpart} 0x04000000 rootfs.cpio.gz.u-boot; bootm 0x00200000 0x04000000 0x00100000 fi bootm 0x00200000 - 0x00100000 fi # If booted from qspi if test "${boot_target}" = "xspi0" || test "${boot_target}" = "qspi" || test "${boot_target}" = "qspi0"; then sf probe 0 0 0; # Load the contents of qspi offset address 0x5A0000, length 0xA40000 to 0x10000000 # 0x5A0000 and 0xA40000 correspond to the image.ub of the qspi space division above sf read 0x10000000 0x5A0000 0xA40000 # Boot from 0x10000000 bootm 0x10000000; echo "Booting using Fit image failed"
sf read 0x00200000 0x1000000 0x500000 sf read 0x04000000 0x1580000 0xA00000 bootm 0x00200000 0x04000000 0x00100000; echo "Booting using Separate images failed" fi if test "${boot_target}" = "nand" || test "${boot_target}" = "nand0"; then nand info; nand read 0x10000000 0x1080000 0x6400000 bootm 0x10000000; echo "Booting using Fit image failed"
nand read 0x00200000 0x1000000 0x3200000 nand read 0x04000000 0x4600000 0x3200000 bootm 0x00200000 0x04000000 0x00100000; echo "Booting using Separate images failed" fidoneЕсли режим загрузки — qspi, то и U-Boot, и образ будут загружены из флэш-памяти qspi.
Если режим загрузки — mmc0 или mmc1, то и U-Boot, и образ будут загружены из mmc.
Исходя из предыдущего анализа файла boot.src, если вы хотите загрузить U-Boot из флэш-памяти qspi и загрузить образ из mmc, вам необходимо изменить файл boot.src.
Поскольку файл boot.src сам по себе имеет проверку CRC, прямое изменение содержимого boot.src приведет к сбою проверки boot.src, что предотвратит запуск ядра.
boot.src генерируется из шаблона components/yocto/layers/meta-xilinx/meta-xilinx-bsp/recipes-bsp/u-boot/u-boot-zynq-scr/boot.cmd.generic, поэтому вы можете изменить файл boot.cmd.generic.
Однако файл boot.cmd.generic может быть автоматически перезаписан во время petalinux-config.
Разумный метод модификации — добавить файл u-boot-zynq-scr.bbappend и папку u-boot-zynq-scr в project-spec/meta-user/recipes-bsp/uboot/.
Исправление загрузочного скрипта U-Boot в Petalinux 2021.1
qspi-flash по-прежнему можно разбить на разделы, следуя инструкциям выше, включая petalinux-config и U-Boot config;
Создайте файл u-boot-zynq-scr.bbappend и папку u-boot-zynq-scr в project-spec/meta-user/recipes-bsp/uboot/
xxxxxxxxxx# u-boot-zynq-scr.bbappend file content as follows:
FILESEXTRAPATHS_prepend := "${THISDIR}/u-boot-zynq-scr:"
SRC_URI += "file://boot.cmd.generic"Скопируйте файл components/yocto/layers/meta-xilinx/meta-xilinx-bsp/recipes-bsp/u-boot/u-boot-zynq-scr/boot.cmd.generic в папку u-boot-zynq-scr, затем измените этот файл:
x
# This is a boot script for U-Boot# Generate boot.scr:# mkimage -c none -A arm -T script -d boot.cmd.default boot.scr#################@@PRE_BOOTENV@@
for boot_target in ${boot_targets};do echo "Trying to load boot images from ${boot_target}" if test "${boot_target}" = "jtag" ; then @@KERNEL_BOOTCMD@@ @@KERNEL_LOAD_ADDRESS@@ @@RAMDISK_IMAGE_ADDRESS@@ @@DEVICETREE_ADDRESS@@ fi if test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1" ; then if test -e ${devtype} ${devnum}:${distro_bootpart} /@@UENV_TEXTFILE@@; then fatload ${devtype} ${devnum}:${distro_bootpart} @@UENV_MMC_LOAD_ADDRESS@@ @@UENV_TEXTFILE@@; echo "Importing environment(@@UENV_TEXTFILE@@) from ${boot_target}..." env import -t @@UENV_MMC_LOAD_ADDRESS@@ $filesize if test -n $uenvcmd; then echo "Running uenvcmd ..."; run uenvcmd; fi fi if test -e ${devtype} ${devnum}:${distro_bootpart} /@@FIT_IMAGE@@; then fatload ${devtype} ${devnum}:${distro_bootpart} @@FIT_IMAGE_LOAD_ADDRESS@@ @@FIT_IMAGE@@; bootm @@FIT_IMAGE_LOAD_ADDRESS@@; fi if test -e ${devtype} ${devnum}:${distro_bootpart} /@@KERNEL_IMAGE@@; then fatload ${devtype} ${devnum}:${distro_bootpart} @@KERNEL_LOAD_ADDRESS@@ @@KERNEL_IMAGE@@;; fi if test -e ${devtype} ${devnum}:${distro_bootpart} /system.dtb; then fatload ${devtype} ${devnum}:${distro_bootpart} @@DEVICETREE_ADDRESS@@ system.dtb; fi if test -e ${devtype} ${devnum}:${distro_bootpart} /@@RAMDISK_IMAGE1@@ && test "${skip_tinyramdisk}" != "yes"; then fatload ${devtype} ${devnum}:${distro_bootpart} @@RAMDISK_IMAGE_ADDRESS@@ @@RAMDISK_IMAGE1@@; @@KERNEL_BOOTCMD@@ @@KERNEL_LOAD_ADDRESS@@ @@RAMDISK_IMAGE_ADDRESS@@ @@DEVICETREE_ADDRESS@@ fi if test -e ${devtype} ${devnum}:${distro_bootpart} /@@RAMDISK_IMAGE@@ && test "${skip_ramdisk}" != "yes"; then fatload ${devtype} ${devnum}:${distro_bootpart} @@RAMDISK_IMAGE_ADDRESS@@ @@RAMDISK_IMAGE@@; @@KERNEL_BOOTCMD@@ @@KERNEL_LOAD_ADDRESS@@ @@RAMDISK_IMAGE_ADDRESS@@ @@DEVICETREE_ADDRESS@@ fi @@KERNEL_BOOTCMD@@ @@KERNEL_LOAD_ADDRESS@@ - @@DEVICETREE_ADDRESS@@ fi if test "${boot_target}" = "xspi0" || test "${boot_target}" = "qspi" || test "${boot_target}" = "qspi0"; then ## This if is the added part: determine whether there is an image.ub file on mmc 1::${distro_bootpart} if test -e mmc 1:${distro_bootpart} /@@FIT_IMAGE@@; then echo "try to boot using mmc Fit image" # If so, load it to the FIT_IMAGE_LOAD_ADDRESS address (corresponding to 0x1000000) fatload mmc 1:${distro_bootpart} @@FIT_IMAGE_LOAD_ADDRESS@@ @@FIT_IMAGE@@; # Boot from FIT_IMAGE_LOAD_ADDRESS address bootm @@FIT_IMAGE_LOAD_ADDRESS@@; echo "Booting using mmc Fit image failed" fi # If there is no image.ub file on mmc, image.ub will still be loaded from qspi echo "try to boot using qspi Fit image" sf probe 0 0 0; sf read @@FIT_IMAGE_LOAD_ADDRESS@@ @@QSPI_FIT_IMAGE_OFFSET@@ @@QSPI_FIT_IMAGE_SIZE@@ bootm @@FIT_IMAGE_LOAD_ADDRESS@@; echo "Booting using Fit image failed"
sf read @@KERNEL_LOAD_ADDRESS@@ @@QSPI_KERNEL_OFFSET@@ @@QSPI_KERNEL_SIZE@@ sf read @@RAMDISK_IMAGE_ADDRESS@@ @@QSPI_RAMDISK_OFFSET@@ @@QSPI_RAMDISK_SIZE@@ @@KERNEL_BOOTCMD@@ @@KERNEL_LOAD_ADDRESS@@ @@RAMDISK_IMAGE_ADDRESS@@ @@DEVICETREE_ADDRESS@@; echo "Booting using Separate images failed" fi if test "${boot_target}" = "nand" || test "${boot_target}" = "nand0"; then nand info; nand read @@FIT_IMAGE_LOAD_ADDRESS@@ @@NAND_FIT_IMAGE_OFFSET@@ @@NAND_FIT_IMAGE_SIZE@@ bootm @@FIT_IMAGE_LOAD_ADDRESS@@; echo "Booting using Fit image failed"
nand read @@KERNEL_LOAD_ADDRESS@@ @@NAND_KERNEL_OFFSET@@ @@NAND_KERNEL_SIZE@@ nand read @@RAMDISK_IMAGE_ADDRESS@@ @@NAND_RAMDISK_OFFSET@@ @@NAND_RAMDISK_SIZE@@ @@KERNEL_BOOTCMD@@ @@KERNEL_LOAD_ADDRESS@@ @@RAMDISK_IMAGE_ADDRESS@@ @@DEVICETREE_ADDRESS@@; echo "Booting using Separate images failed" fidoneВыполните предыдущие шаги: после сборки petalinux и упаковки скопируйте файлы BOOT.bin, boot.src, image.ub и zynq_fsbl.elf в Windows и с помощью Vitis запишите их в qspi-flash; скопируйте файл image.ub в первый раздел eMMC и извлеките rootfs во второй раздел eMMC.